package top.xana.acg.anime.ui.page

import android.graphics.Color
import android.os.Bundle
import android.widget.TextView
import androidx.core.os.bundleOf
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.RecyclerView
import com.android.iplayer.controller.VideoController
import com.android.iplayer.listener.OnPlayerEventListener
import com.android.iplayer.widget.VideoPlayer
import com.android.iplayer.widget.WidgetFactory
import com.drake.brv.utils.bindingAdapter
import com.drake.brv.utils.grid
import com.drake.brv.utils.linear
import com.drake.brv.utils.setup
import top.xana.acg.anime.BR
import top.xana.acg.anime.R
import top.xana.acg.anime.SearchSource
import top.xana.acg.anime.databinding.FragmentAnimePlayerBinding
import top.xana.acg.anime.decoder.AliPlayerFactory
import top.xana.acg.anime.model.Anime
import top.xana.acg.anime.model.Episode
import top.xana.acg.anime.model.SourceUi
import top.xana.acg.anime.ui.viewmodel.AnimeViewModel
import top.xana.acg.anime.utils.LogE
import top.xana.acg.anime.utils.cast
import top.xana.acg.anime.utils.contextNotNull
import top.xana.acg.anime.utils.navTo
import top.xana.acg.base.BaseFragment


class AnimePlayerFragment :
    BaseFragment<FragmentAnimePlayerBinding>(R.layout.fragment_anime_player) {

    companion object {
        @JvmStatic
        fun newInstance() = AnimePlayerFragment()

        const val TAG = "AnimePlayerFragment"

        private const val KEY_ANIME = "key_anime"

        private const val KEY_SOURCE = "key_source"

        private const val regexType = "类型"

        private const val regexBrief = "简介"

        @JvmStatic
        fun createBundle(source: SearchSource, anime: Anime) = bundleOf(
            KEY_SOURCE to source,
            KEY_ANIME to anime
        )
    }

    private val viewModel by activityViewModels<AnimeViewModel>()

    private var searchSource = SearchSource.Bimi

    private var mVideoPlayer: VideoPlayer? = null

    private var anime = Anime()

    override fun initArgs(bundle: Bundle?) {
        initWindowArgs()
        super.initArgs(bundle)
        arguments?.let {
            searchSource = it.getSerializable(KEY_SOURCE).cast() ?: searchSource
            anime = it.getSerializable(KEY_ANIME).cast() ?: anime
        }
    }

    private fun initWindowArgs() {
        /*        val windowLp = activity?.window?.attributes
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            windowLp?.layoutInDisplayCutoutMode =
                WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
        }*/
        activity?.window?.run {
            statusBarColor = Color.BLACK
        }
    }

    override fun initView() {
        super.initView()
        binding.vm = viewModel
        binding.anime = viewModel.currentPlayingAnime
        binding.listEpisode.linear(orientation = RecyclerView.HORIZONTAL).setup {
            var lastPos: Int? = null
            modelId = BR.episode
            addType<Episode>(R.layout.item_episode_view)
            onClick(R.id.frameEpisode) {
                val entity = getModel<Episode>()
                viewModel.loadPlayUrl(
                    searchSource = searchSource,
                    title = entity.title,
                    uri = entity.desc,
                    callback = this@AnimePlayerFragment::realPlay
                )
                lastPos?.let {
                    getModelOrNull<Episode>(it)?.selected = false
                    notifyItemChanged(it)
                }
                getModelOrNull<Episode>()?.selected = true
                notifyItemChanged(modelPosition)
            }
            onBind { lastPos = lastPos ?: modelPosition }
        }
        binding.listSource.linear(orientation = RecyclerView.HORIZONTAL).setup {
            var lastPos: Int? = null
            addType<SourceUi>(R.layout.item_source_view)
            onBind {
                val entity = getModelOrNull<SourceUi>()
                lastPos = lastPos ?: kotlin.run {
                    entity?.selected = true
                    modelPosition
                }
                val textView = findView<TextView>(R.id.textSource)
                itemView.isSelected = entity?.selected == true
                textView.text = entity?.title
            }
            onClick(R.id.textSource) {
                val entity = getModelOrNull<SourceUi>()
                lastPos?.let {
                    getModelOrNull<SourceUi>()?.selected = false
                    notifyItemChanged(it)
                }
                entity?.selected = true
                notifyItemChanged(modelPosition)
                with(binding.listEpisode) {
                    bindingAdapter.models = entity?.episodes
                    scrollTo(0, 0)
                }

            }
        }

        binding.listRelated.grid(3).setup {
            addType<Anime>(R.layout.item_related_view)
            modelId = BR.anime
            onClick(R.id.frameAnime) {
                itemView.navTo(
                    R.id.toPagePlayer,
                    createBundle(SearchSource.Bimi, getModel())
                )
            }
        }
        fetchDate()
    }


    private fun fetchDate() {
        initDecoder()
        viewModel.loadSource(searchSource, anime.uri, this::setSource)
        viewModel.loadAnimeDetail(searchSource, anime.uri, this::setDetail)
        viewModel.loadRelated(searchSource, anime.uri, this::setRelated)
    }

    private fun initDecoder() {
        mVideoPlayer = binding.videoPlayer
        binding.videoPlayer.setOnPlayerActionListener(object : OnPlayerEventListener() {
            override fun createMediaPlayer() =
                AliPlayerFactory.create().createPlayer(contextNotNull)
        })
    }

    private fun setSource(sourceUis: List<SourceUi>) {
        binding.listSource.bindingAdapter.models = sourceUis
        binding.listEpisode.bindingAdapter.models = sourceUis.getOrNull(0)?.episodes
    }

    private fun setRelated(animeList: List<Anime>) {
        binding.listRelated.bindingAdapter.models = animeList
    }

    private fun setDetail(anime: Anime) {
        binding.anime = anime
        anime.extra?.cast<Iterable<String>>()?.forEach {
            if (it.contains(regexType)) binding.type = it
            else if (it.contains(regexBrief)) {
                binding.desc = it
                return@forEach
            }
        }
    }


    private fun realPlay(title: String, playUrl: String) {
        LogE("loading...playUrl\n\t\t $playUrl", TAG)
        val mVideoPlayer = binding.videoPlayer
        val controller = VideoController(mVideoPlayer.context) //创建一个默认控制器
        mVideoPlayer.controller = controller //将播放器绑定到控制器
        WidgetFactory.bindDefaultControls(controller) //一键使用默认UI交互组件绑定到控制器(需集成：implementation 'com.github.hty527.iPlayer:widget:lastversion')
        controller.setTitle(anime.title + " " + title)
        mVideoPlayer.setDataSource(playUrl)
        mVideoPlayer.prepareAsync()
    }

    override fun onDestroy() {
        super.onDestroy()
        mVideoPlayer?.onDestroy()
    }

    override fun onPause() {
        super.onPause()
        binding.videoPlayer.onPause()
    }

    override fun onResume() {
        super.onResume()
        binding.videoPlayer.onResume()
    }


}